﻿using System;
using System.Collections.Generic;
using System.IO;

namespace Game.Lib.ztPackets
{
    public class AckPacket : Packet
    {
        /// <summary>
        /// List of packets that were fully recieved
        /// </summary>
        public uint[] Acks;

        public Nack[] Nacks;

        public override int Length
        {
            get
            {
                int ret = Acks.Length * 4;
                foreach (Nack n in Nacks) ret += n.Length;
                return ret;
            }
        }

        public override byte[] ToBytes()
        {
            MemoryStream ms = new MemoryStream(Length);
            
            ms.Write(BitConverter.GetBytes(Acks.Length), 0, 4);
            for(int i= 0; i < Acks.Length; i++)
            {
                ms.Write(BitConverter.GetBytes(Acks[i]), 0, 4);
            }
            
            ms.Write(BitConverter.GetBytes(Nacks.Length), 0, 4);
            for(int i= 0; i < Nacks.Length; i++)
            {
                byte[] data = Nacks[i].ToBytes();
                ms.Write(data, 0, data.Length);
            }
            
            return GetTotalBuffer(ms.ToArray());
        }

        public override void FromBytes(byte[] data, int pos)
        {
            int ackLen = BitConverter.ToInt32(data, pos);
            pos += 4;
            List<uint> temp = new List<uint>(ackLen);
            for(int i = 0; i < ackLen; i++)
            {
                temp.Add(BitConverter.ToUInt32(data, pos));
                pos += 4;
            }
            Acks = temp.ToArray();
            
            int nackLen = BitConverter.ToInt32(data, pos);
            pos += 4;
            List<Nack> temp2 = new List<Nack>(nackLen);
            for(int i = 0; i < nackLen; i++)
            {
                Nack n = new Nack(data, pos);
                pos += n.Length;
                temp2.Add(n);
            }
            Nacks = temp2.ToArray();
        }
    }
    
    public struct Nack
    {
        public uint PacketID;
        public ushort[] MissingParts;
        
        public int Length
        {
            get
            {
                return 6 + MissingParts.Length * 2;
            }
        }
        
        public Nack(byte[] data, int pos)
        {
            PacketID = BitConverter.ToUInt32(data, pos);
            ushort len = BitConverter.ToUInt16(data, pos + 4);
            List<ushort> temp = new List<ushort>(len);
            for (int i = 0; i < len; i++)
            {
                temp.Add(BitConverter.ToUInt16(data, pos + 6 + i * 2));
            }
            MissingParts = temp.ToArray();
        }
        
        public byte[] ToBytes()
        {
            byte[] ret = new byte[6 + MissingParts.Length * 2];
            Buffer.BlockCopy(BitConverter.GetBytes(PacketID), 0, ret, 0, 4);
            Buffer.BlockCopy(BitConverter.GetBytes((ushort)MissingParts.Length), 0, ret, 4, 2);
            for(int i = 0; i < MissingParts.Length; i++)
            {
                Buffer.BlockCopy(BitConverter.GetBytes(MissingParts[i]), 0, ret, i * 2 + 6, 2);
            }
            return ret;
        }
    }
}
